#include <iostream>
#include "httplib.h"
#include "add_contact.pb.h"

using namespace httplib;
using namespace std;

// ⾃定义异常类
class ContactException
{
private:
    std::string message;

public:
    ContactException(std::string str = "A problem") : message{str} {}
    std::string what() const { return message; }
};

void printContact(add_contact::AddContactRequest &req)
{
    cout << "姓名:" << req.name() << endl;
    cout << "年龄:" << req.age() << endl;
    for (int j = 0; j < req.phone_size(); j++)
    {
        const add_contact::AddContactRequest_Phone &phone = req.phone(j);
        cout << "联系电话：" << phone.number()
             << " (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
        // phone.type() 获取的是int值，phone.PhoneType_Name(phone.type())是根据int值转为对应的常量名（string）。
    }
}

static unsigned int random_char() {
    // ⽤于随机数引擎获得随机种⼦
    std::random_device rd;
    // mt19937是c++11新特性，它是⼀种随机数算法，⽤法与rand()函数类似，但是mt19937具有速度快，周期⻓的特点
    // 作⽤是⽣成伪随机数
    std::mt19937 gen(rd());
    // 随机⽣成⼀个整数i 范围[0, 255]
    std::uniform_int_distribution<> dis(0, 255);
    return dis(gen);
}
// ⽣成 UUID （通⽤唯⼀标识符）
static std::string generate_hex(const unsigned int len) {
    std::stringstream ss;
    // ⽣成 len 个16进制随机数，将其拼接⽽成
    for (auto i = 0; i < len; i++) {
        const auto rc = random_char();
        std::stringstream hexstream;  
        hexstream << std::hex << rc;  // 生成的随机数转为16进制流
        auto hex = hexstream.str();  // 转为字符串形式
        ss << (hex.length() < 2 ? '0' + hex : hex);
    }
    return ss.str();
}


int main()
{
    cout << "--------服务启动---------" << endl;
    Server server;

    server.Post("/contacts/add", [](const Request &req, Response &res)
    {
        cout << "接收到post请求!" << endl;

        // 反序列化
        add_contact::AddContactRequest request;
        add_contact::AddContactResponse response;
        try
        {
            if (!request.ParseFromString(req.body))
            {
                throw ContactException("AddContactRequest 反序列化失败");
            }

            // 新增联系人持久化逻辑--》打印新增联系人信息
            printContact(request);

            // 构造返回结果 response.body
            response.set_success(true);
            response.set_uid(generate_hex(10));

            // 把response响应结果进行序列化，反馈给客户端
            string response_str;
            if (!response.SerializeToString(&response_str))
            {
                throw ContactException("ADDcontactRequest序列化失败");
            }
            res.status = 200;
            res.body = response_str;
            res.set_header("Contact-Type", "application/protobuf");
        }
        catch (const ContactException &e)
        {
            res.status = 500;
            response.set_success(false);
            response.set_error_desc(e.what());
            string response_str;
            if (response.SerializeToString(&response_str))
            {
                res.body = response_str;
                res.set_header("Content-type", "application/protobuf");
            }
            cout << "/contact/add 发生异常， 信息：" << e.what() << endl;
        } });

    // 开放端口，接收任何ip客户端的请求
    server.listen("0.0.0.0", 8080);

    return 0;
}